#include "dbmanager.h"
#include <cstdlib>

std::shared_ptr<DBManager> DBManager::m_instance(new DBManager());

DBManager::DBManager()
{
    mydb = std::make_shared<MyDB>();
    mydb->initDB("localhost", "lvqiang", "XX1516305754", "zjh");
}

DBManager::~DBManager()
{
    
}

std::shared_ptr<DBManager>& DBManager::GetInstance()
{
    return m_instance;
}

bool DBManager::IsExistUserName(const std::string& username)
{
    std::string sql = "select * from userinfo where username = " + std::string("\"") + username + std::string("\"");
    MySQLRes::ptr mysqlRes = mydb->exeSQL(sql);  
    if(mysqlRes->GetRowCount())
    {
        return true;
    }
    return false;
}

bool DBManager::CreateUser(const std::string& userName, std::string& pwd)
{
    if(IsExistUserName(userName))
    {
        return false;
    }
    //todo　生成一个随机数
    int num = std::rand() % 19;
    std::string iconName = std::to_string(num);
    std::string sql = "insert into userinfo values(null, \"" + userName + "\", \"" + pwd + "\", " + "0, " + "\"" + iconName + "\"," + "5000)";
    mydb->exeSQL(sql);
    return true;
}

bool DBManager::IsMatch(const std::string& username, const std::string& password, int& playerId)
{
    std::string sql = "select password, id from userinfo where username = " + std::string("\"" + username + std::string("\""));
    MySQLRes::ptr mysqlRes = mydb->exeSQL(sql); 
    if(mysqlRes->GetRowCount() == 0)
    {
        return false;
    }
    else
    {
        MYSQL_ROW mysqlRow = mysql_fetch_row(mysqlRes->GetData().get());
        if(mysqlRow[0] == password)
        {
            playerId = std::atoi(mysqlRow[1]);
            return true;
        }
    }
    return false;
}

void DBManager::GetUserInfo(const std::string& username, proto::UserInfoResponse& userinfo)
{
    std::string sql = "select iconname, coin from userinfo where username = " + std::string("\"") + username + std::string("\"");
    MySQLRes::ptr mysqlRes = mydb->exeSQL(sql);
    MYSQL_ROW mysqlRow = mysql_fetch_row(mysqlRes->GetData().get());
    userinfo.set_iconname(mysqlRow[0]);
    userinfo.set_coin(std::atoi(mysqlRow[1]));
}

void DBManager::GetRankList(std::vector<proto::RankListResponse>& rankList)
{
    std::string sql = "select username, coin from userinfo order by coin desc";
    MySQLRes::ptr mysqlRes = mydb->exeSQL(sql);
    int num_rows = mysql_num_rows(mysqlRes->GetData().get());
    for(int i = 0; i < num_rows; i++)
    {
        MYSQL_ROW row = mysql_fetch_row(mysqlRes->GetData().get());
        proto::RankListResponse response;
        response.set_username(row[0]);
        response.set_coin(std::atoi(row[1]));
        rankList.push_back(response);
    }
}

int DBManager::UpdateCoinCount(const std::string& username, int coincount)
{
    std::string sql1 = "select coin from userinfo where username = " + std::string("\"") + username + std::string("\"");
    MySQLRes::ptr mysqlRes = mydb->exeSQL(sql1);
    MYSQL_ROW row = mysql_fetch_row(mysqlRes->GetData().get());
    int oldCoinCount = std::atoi(row[0]);
    int newCoinCount = coincount + oldCoinCount;
    std::string sql2 = "update userinfo set coin = " + std::to_string(newCoinCount) + std::string(" where username = ") + std::string("\"") + username + std::string("\"");
    mydb->exeSQL(sql2);
    return newCoinCount;
}

int DBManager::GetCoin(const std::string& username)
{
    std::string sql = "select coin from userinfo where username = " + std::string("\"") + username + std::string("\"");
    MySQLRes::ptr mysqlRes = mydb->exeSQL(sql);
    MYSQL_ROW mysqlRow = mysql_fetch_row(mysqlRes->GetData().get());
    return std::atoi(mysqlRow[0]);
}